#include "./myControl.h"
#include "./myWindowlet.h"

namespace Framework
{
	using namespace Sky;

myControl::~myControl()
{
	detachCurrent();
}
TBool myControl::setState( TBool b,TUint attr )
{
	TUint val = m_AttrValue;
	/*if(m_AttrFlag & attr)
	{
		if(b)
		{
			val |= attr;
		}
		else
		{
			val &= (~attr);
		}
		if(val != m_AttrValue)
		{
			if(onStateChanged(val ^ m_AttrValue) == vTrue)
			{
				m_AttrValue = val;
				return vTrue;
			}
		}
	}*/
	return vFalse;
}

TBool myControl::setVisible( TBool visible )
{
	//return setState(visible,Attr_Visible);
	if(visible)
		m_AttrValue |= Attr_Visible;
	else
		m_AttrValue &= (~Attr_Visible);
	return vTrue;
}

TBool myControl::setDrawBeforeChildren( TBool bDraw )
{
	if(bDraw)
	{
		m_AttrValue |= Attr_DrawBeforeChildren;
	}
	else
	{
		m_AttrValue &= (~Attr_DrawBeforeChildren);
	}
	return vTrue;
}

TBool myControl::setDrawAfterChildere( TBool bDraw )
{
	if(bDraw)
	{
		m_AttrValue |= Attr_DrawAfterChildren;
	}
	else
	{
		m_AttrValue &= (~Attr_DrawAfterChildren);
	}
	return vTrue;
}

TBool myControl::setEnable( TBool enable )
{
	//return setState(enable,Attr_Enabled);
	if(enable)
		m_AttrValue |= Attr_Enabled;
	else
		m_AttrValue &= (~Attr_Enabled);
	return vTrue;
}

TBool myControl::setFocus( TBool focus )
{
	//return setState(focus,Attr_Focused);
	if(m_AttrFlag & Attr_Focused)
	{
		TUint val = m_AttrValue;
		if(focus)
			val |= Attr_Focused;
		else
			val &= (~Attr_Focused);
		if(val ^ m_AttrValue)
		{
			m_AttrValue = val;
			return vTrue;
		}
	}
	return vFalse;
}

TVoid myControl::setCanFocused( TBool bCan )
{
	if(bCan)
	{
		m_AttrFlag |= Attr_Focused;
	}
	else
	{
		m_AttrFlag &= (~Attr_Focused);
	}
}

myControl::myControl():
m_AttrFlag(0xffffffff),
m_AttrValue(Attr_Enabled|Attr_Visible|Attr_HandleEvent|Attr_DrawBeforeChildren),
m_ctrlID(0),
m_Rect(0,0,240,320)
{
	m_Rect.x = 0;
	m_Rect.y = 0;
	m_Rect.w = 0;
	m_Rect.h = 0;
}

myControl::myControl( TUint ctrlid ):
m_AttrFlag(0xffffffff),
m_AttrValue(Attr_Enabled|Attr_Visible|Attr_HandleEvent|Attr_DrawBeforeChildren),
m_ctrlID(ctrlid),
m_Rect(0,0,240,320)
{
	m_Rect.x = 0;
	m_Rect.y = 0;
	m_Rect.w = 0;
	m_Rect.h = 0;
}

TBool myControl::isVisible()
{
	return isVisible(m_AttrValue);
}

TBool myControl::isEnabled()
{
	return isEnabled(m_AttrValue);
}

TBool myControl::isFocused()
{
	return isFocused(m_AttrValue);
}


TBool myControl::isDrawBeforeChildren()
{
	return isDrawBeforeChildren(m_AttrValue);
}

TBool myControl::isDrawAfterChildren()
{
	return isDrawAfterChildren(m_AttrValue);
}

TBool myControl::canFocused()
{
	return (Attr_Focused & m_AttrFlag) != vNull;
}

myControl& myControl::setSize( TInt w,TInt h )
{
	m_Rect.w = w; m_Rect.h = h; 
	return *this;
}

myControl& myControl::setPosition( TInt x,TInt y )
{
	m_Rect.x = x; 
	m_Rect.y = y;
	return *this;
}

Sky::NValue::MsgStatus myControl::handleAttached( myEventManager* manager,Message* msg )
{
	if(onAttached(manager,msg) == vIntercepted)return vIntercepted;
	return _delegators.invoke(&myControl::handleAttached,manager,msg);
}

Sky::NValue::MsgStatus myControl::handleDetached( myEventManager* manager,Message* msg )
{
	if(onAttached(manager,msg) == vIntercepted)return vIntercepted;
	return _delegators.invoke(&myControl::handleDetached,manager,msg);
}

Sky::NValue::MsgStatus myControl::handlePaint( myEventManager* manager,Message* msg )
{
	if(onPaint(manager,msg) == vIntercepted)return vIntercepted;
	return _delegators.invoke(&myControl::handlePaint,manager,msg);
}

Sky::NValue::MsgStatus myControl::handleCreated( myEventManager* manager,Message* msg )
{
	if(onCreated(manager,msg) == vIntercepted)return vIntercepted;
	return _delegators.invoke(&myControl::handleCreated,manager,msg);
}

Sky::NValue::MsgStatus	myControl::handleDeleting(myEventManager* manager,Message* msg)
{
	if(onDeleting(manager,msg) == vIntercepted)return vIntercepted;
	return _delegators.invoke(&myControl::handleDeleting,manager,msg);
}

Sky::NValue::MsgStatus myControl::handleInput( myEventManager* manager,Message* msg )
{
	if(onInput(manager,msg) == vIntercepted)return vIntercepted;
	return _delegators.invoke(&myControl::handleInput,manager,msg);
}

Sky::NValue::MsgStatus myControl::handleFocusChange( myEventManager* manager,Message* msg )
{
	if(onFocusChange(manager,msg) == vIntercepted)return vIntercepted;
	return _delegators.invoke(&myControl::handleFocusChange,manager,msg);
}

Sky::NValue::MsgStatus myControl::handleFocusPrev( myEventManager* manager,Message* msg )
{
	if(onFocusPrev(manager,msg) == vIntercepted)return vIntercepted;
	return _delegators.invoke(&myControl::handleFocusPrev,manager,msg);
}

Sky::NValue::MsgStatus myControl::handleFocusNext( myEventManager* manager,Message* msg )
{
	if(onFocusNext(manager,msg) == vIntercepted)return vIntercepted;
	return _delegators.invoke(&myControl::handleFocusNext,manager,msg);
}

Sky::NValue::MsgStatus myControl::handleSizeChanged( myEventManager* manager,Message* msg )
{
	if(onSizeChanged(manager,msg) == vIntercepted)return vIntercepted;
	return _delegators.invoke(&myControl::handleSizeChanged,manager,msg);
}

Sky::NValue::MsgStatus myControl::handleTimer( myEventManager* manager,Message* msg )
{
	if(onTimer(manager,msg) == vIntercepted)return vIntercepted;
	return _delegators.invoke(&myControl::handleTimer,manager,msg);
}


//
//myControl* myControl::attachChild( myControl* child )
//{
//	myControlManager manager;
//	manager.setRoot(this);
//	if(manager.attachLastChildOf(this,child))
//		return child;
//	return vNull;
//}
//
//myControl* myControl::detachChild( myControl* child )
//{
//	myControlManager manager;
//	manager.setRoot(this);
//	return manager.detach(child);;
//}
//
//myControl* myControl::attachNext( myControl* next )
//{
//	myControlManager manager;
//	manager.setRoot(this);
//	if(manager.attachNextSiblingOf(this,next))
//		return next;
//	return vNull;
//}
//
//myControl* myControl::detachNext()
//{
//	myControlManager manager;
//	manager.setRoot(this);
//	return manager.detachNextSiblingOf(this);;
//}
//
//myControl* myControl::getFirstChild()
//{
//	myControlManager manager;
//	manager.setRoot(this);
//	return manager.getFirstChildOf(this);
//}
//
//myControl* myControl::getLastChild()
//{
//	myControlManager manager;
//	manager.setRoot(this);
//	return manager.getLastChildOf(this);
//}
//
//myControl* myControl::detachFirstChild()
//{
//	myControlManager manager;
//	manager.setRoot(this);
//	return manager.detachFirstChildOf(this);
//}

myControl* myControlManager::getParentLastTraverseOf( myControl* control )
{
	return (myControl*)m_Manager.getParentLastTraverseOf(control);
}

TBool myControlManager::attachLastChildOf( myControl* control,myControl* child )
{
	if(m_Manager.attachLastChildOf(control,child))
	{
		myCtrlMessage ce(&myControl::handleAttached,this);
		return vFailed == child->handleAttached(m_EventManager,&ce) ? vFalse : vTrue;
	}
	return vFalse;
}

TBool myControlManager::attachFirstChildOf( myControl* control,myControl* child )
{
	if( m_Manager.attachFirstChildOf(control,child))
	{
		myCtrlMessage ce(&myControl::handleAttached,this);
		return vFailed == child->handleAttached(m_EventManager,&ce) ? vFalse : vTrue;
	}
	return vFalse;
}

TBool myControlManager::attachNextSiblingOf( myControl* control,myControl* sibling )
{
	if( m_Manager.attachNextSiblingOf(control,sibling))
	{
		myCtrlMessage ce(&myControl::handleAttached,this);
		return vFailed == sibling->handleAttached(m_EventManager,&ce) ? vFalse : vTrue;
	}
	return vFalse;
}

TBool myControlManager::attachPrevSiblingOf( myControl* control,myControl* sibling )
{
	if( m_Manager.attachPrevSiblingOf(control,sibling))
	{
		myCtrlMessage ce(&myControl::handleAttached,this);
		return vFailed == sibling->handleAttached(m_EventManager,&ce) ? vFalse : vTrue;
	}
	return vFalse;
}

myControl* myControlManager::detachLastChildOf( myControl* control )
{
	myControl* ret = (myControl*)m_Manager.detachLastChildOf(control);
	if(ret)
	{
		myCtrlMessage ce(&myControl::handleDetached,this);
		ret->handleDetached(m_EventManager,&ce);
	}
	return ret;
}

myControl* myControlManager::detachFirstChildOf( myControl* control )
{
	myControl* ret = (myControl*)m_Manager.detachFirstChildOf(control);
	if(ret)
	{
		myCtrlMessage ce(&myControl::handleDetached,this);
		ret->handleDetached(m_EventManager,&ce);
	}
	return ret;
}

myControl* myControlManager::detachPrevSiblingOf( myControl* control )
{
	myControl* ret = (myControl*)m_Manager.detachPrevSiblingOf(control);
	if(ret)
	{
		myCtrlMessage ce(&myControl::handleDetached,this);
		ret->handleDetached(m_EventManager,&ce);
	}
	return ret;
}

myControl* myControlManager::detachNextSiblingOf( myControl* control )
{
	myControl* ret = (myControl*)m_Manager.detachNextSiblingOf(control);
	if(ret)
	{
		myCtrlMessage ce(&myControl::handleDetached,this);
		ret->handleDetached(m_EventManager,&ce);
	}
	return ret;
}

myControl* myControlManager::detach( myControl* control )
{
	myControl* ret = (myControl*)m_Manager.detach(control);
	if(ret)
	{
		myCtrlMessage ce(&myControl::handleAttached,this);
		ret->handleDetached(m_EventManager,&ce);
	}
	return ret;
}

myControl* myControlManager::detachAllChildrenOf( myControl* control )
{
	xAssert(control);
	TreeNode* cur = TreeManager::cast(control);
	TreeNode* fc = cur->getFirstChild();
	cur->m_FirstChild = vNull;
	cur->m_LastChild = vNull;
	TreeNode* temp = fc;
	myCtrlMessage ce(&myControl::handleAttached,this);
	while(temp)
	{
		((myControl*)control)->handleDetached(m_EventManager,&ce);
		temp->m_Parent = vNull;
	}
	return (myControl*)fc;
}

myControl* myControlManager::getParentOf( myControl* control )
{
	return (myControl*)m_Manager.getParentOf(control);
}

myControl* myControlManager::getLastChildOf( myControl* control )
{
	return (myControl*)m_Manager.getLastChildOf(control);
}

myControl* myControlManager::getFirstChildOf( myControl* control )
{
	return (myControl*)m_Manager.getFirstChildOf(control);
}

myControl* myControlManager::getPrevSiblingOf( myControl* control )
{
	return (myControl*)m_Manager.getPrevSiblingOf(control);
}

myControl* myControlManager::getNextSiblingOf( myControl* control )
{
	return (myControl*)m_Manager.getNextSiblingOf(control);
}

myControl* myControlManager::getParentFirsTraverseOf( myControl* control )
{
	return (myControl*)m_Manager.getParentFirsTraverseOf(control);
}

myControl* myControlManager::getParentFirsTraverseOf_Reverse( myControl* control )
{
	return (myControl*)m_Manager.getParentFirsTraverseOf_Reverse(control);
}

#define xGetAbsRect(rpa,ctrl,t)  do{t = ctrl->getRect();rpa->x += t->x; rpa->y += t->y; rpa->w = t->w; rpa->h = t->h;}while(0)
//#define xGetRevRect(rpa,ctrlFirst,t,pa)  do{t = ctrlFirst->getRect();rpa->x -= t->x; rpa->y -= t->y; rpa->w = pa->w; rpa->h = pa->h;}while(0)
#define xGetRevRect(rnp,rp,ctrl,t)  do{t = ctrl->getRect();rnp->x = rp->x - t->x; rnp->y = rp->y - t->y; rnp->w = rp->w; rnp->h = rp->h;}while(0)

myControl* myControlManager::getParentFirsTraverseWithPositionOf( myControl* ctrl,TRect* ctrlParentAbs,TheSecondVisitedCall callBack,TVoid* pData)
{
	myControl* curCtrl = ctrl;
	TreeNode* root = m_Manager.getRoot();
	myControl* next;
	TreeNode* pTmpNode;
	TRect* temp;

	if (TreeManager::cast(curCtrl)->getFirstChild())
	{//get current node position
		xGetAbsRect(ctrlParentAbs,curCtrl,temp);
		return (myControl*)TreeManager::cast(curCtrl)->getFirstChild();
	}

	if (TreeManager::cast(curCtrl)->getNextSibling())
	{//with same parent node,the position not change
		return (myControl*)TreeManager::cast(curCtrl)->getNextSibling();
	}

	
	pTmpNode = TreeManager::cast(curCtrl)->getParent();
	
	while (pTmpNode) 
	{
		if(pTmpNode == root)
			return vNull;
		//ctrlParentAbs is the absolute rect of pTempNode->getRect()
		//xGetRevRect(ctrlParentAbs,((myControl*)pTmpNode->getParent()->getFirstChild()),temp,((myControl*)pTmpNode->getParent())->getRect());
		xGetRevRect(ctrlParentAbs,ctrlParentAbs,((myControl*)pTmpNode),temp);
		if (pTmpNode->getNextSibling())
		{
			return (myControl*)TreeManager::cast(pTmpNode)->getNextSibling();
		}
		if(callBack)
			callBack((myControl*)pTmpNode,pData,ctrlParentAbs);
		pTmpNode = pTmpNode->getParent();
	}
	return vNull;
}

myControl* myControlManager::getSubTreeParentFirsTraverseOf( myControl* control,myControl* subRoot )
{
	return (myControl*)m_Manager.getSubTreeParentFirsTraverseOf(control,subRoot);
}

myControl* myControlManager::getSubTreeParentFirsTraverseWithPositionOf( myControl* ctrl,myControl* subRoot,TRect* ctrlParentAbs,TRect* nextParentAbs )
{
	myControl* curCtrl = ctrl;
	TreeNode* root = subRoot;
	myControl* next;
	TreeNode* pTmpNode;
	TRect* temp;

	if (TreeManager::cast(curCtrl)->getFirstChild())
	{//get current node position
		//xGetAbsRect(ctrlParentAbs,curCtrl,temp);
		xGetAbsRect(ctrlParentAbs,curCtrl,temp);
		return (myControl*)TreeManager::cast(curCtrl)->getFirstChild();
	}

	if (TreeManager::cast(curCtrl)->getNextSibling())
	{//with same parent node,the position not change
		return (myControl*)TreeManager::cast(curCtrl)->getNextSibling();
	}

	pTmpNode = TreeManager::cast(curCtrl)->getParent();
	TreeNode* child;
	while (pTmpNode) 
	{
		if(pTmpNode == root)
			return vNull;
		//ctrlParentAbs is the absolute rect of pTempNode->getRect()
		//xGetRevRect(ctrlParentAbs,((myControl*)pTmpNode->getParent()->getFirstChild()),temp,((myControl*)pTmpNode->getParent())->getRect());
		xGetRevRect(ctrlParentAbs,ctrlParentAbs,((myControl*)pTmpNode),temp);
		child = pTmpNode->getNextSibling();
		if (child)
		{
			return (myControl*)child;
		}

		pTmpNode = pTmpNode->getParent();
	}
	return vNull;
}

TBool myControlManager::Initialise( myWindowlet* window )
{
	m_Window = window;
	return vTrue;

}

TBool myControlManager::setRoot( myControl* root )
{
	return m_Manager.setRoot(root);
}

myControl* myControlManager::getRoot()
{
	return (myControl*)m_Manager.getRoot();
}

TVoid myControlManager::notifyInvalidateRect( TRect* rect )
{
	xAssert(m_Window);
	m_Window->onAreaInvalidate(rect);
}

myControl* myControlManager::getControl( TUint ctrlID )
{
	
	myControl* ctl = getRoot();
	while(ctl)
	{
		if(ctl->m_ctrlID == ctrlID)
			return ctl;
		else
			ctl = (myControl*)ctl->getNext();
	}
	return vNull;
}

TVoid myControlManager::notifyInvalidateControl( myControl* ctrl )
{
	xAssert(m_Window);
	m_Window->onControlInvalidate(ctrl);
}

myControl* myControlManager::exchange( myControl* thisCtrl,myControl* thatCtrl )
{
	return (myControl*)m_Manager.exchange(thisCtrl,thatCtrl);
}

myControl* myControlManager::focusNext()
{
	return vNull;
}
//TBool myCtrlMessage::translateKeyUpEvent( myEvent* event,KeyInputEvent* inputEvent )
//{
//	if( event->m_Type == EventType_KeyUp )
//	{
//		inputEvent->value = (XKEY)event->m_Param;
//		return vTrue;
//	}
//	return vFalse;
//
//}
//
//TBool myCtrlMessage::translateKeyDnEvent( myEvent* event,KeyInputEvent* inputEvent )
//{
//	if( event->m_Type == EventType_KeyDown )
//	{
//		inputEvent->value = (XKEY)event->m_Param;
//		return vTrue;
//	}
//	return vFalse;
//}
//
//TBool myCtrlMessage::translateKeyRepeatEvent( myEvent* event,KeyInputEvent* inputEvent )
//{
//	if( event->m_Type == EventType_KeyRepeat | event->m_Type == EventType_KeyDown)
//	{
//		inputEvent->value = (XKEY)event->m_Param;
//		return vTrue;
//	}
//	return vFalse;
//}
//
//TBool myCtrlMessage::translateUIFocusPrevEvent( myEvent* event,UIFocusEvent* focusEvent )
//{
//	if(event->m_Type != EventType_UIFocusPrev)
//		return vFalse;
//	focusEvent->currFocus = (myControl*)event->m_pUser;
//	return vTrue;
//}
//
//TBool myCtrlMessage::translateUIFocusNextEvent( myEvent* event,UIFocusEvent* focusEvent )
//{
//	if(event->m_Type != EventType_UIFocusNext)
//		return vFalse;
//	focusEvent->currFocus = (myControl*)event->m_pUser;
//	return vTrue;
//}
//
//TVoid myCtrlMessage::sealUIFocusPrevEvent( myEvent* event,myControl* curFocus )
//{
//	event->m_Type = EventType_UIFocusPrev;
//	event->m_pUser = (TVoid*)curFocus;
//	return;
//}
//
//TVoid myCtrlMessage::sealUIFocusNextEvent( myEvent* event,myControl* curFocus )
//{
//	event->m_Type = EventType_UIFocusNext;
//	event->m_pUser = (TVoid*)curFocus;
//	return;
//}
//
//TVoid myCtrlMessage::sealSpecialTimerEvent( myEvent* event,TUint timerID,TimerEventProc timerProc,TVoid* pUser )
//{
//	event->m_Type = EventType_SpecialTimer;
//	event->m_Param = timerID;
//	event->m_pUser = pUser;
//	event->m_Data = (TUint)(TVoid*)timerProc;
//	return;
//}
//
//TBool myCtrlMessage::translateSpecialTimerEvent( myEvent* event,SpecialTimerEvent* timerEvent )
//{
//	if(event->m_Type != EventType_SpecialTimer)
//		return vFalse;
//	timerEvent->pUser = event->m_pUser;
//	timerEvent->timerID = event->m_Param;
//	timerEvent->timerProc = (TimerEventProc)(TVoid*)event->m_Data;
//	return vTrue;
//}

//TBool myCtrlMessage::translateUIFocusNextEvent( myEvent* event,UIFocusEvent* focusEvent )
//{
//	if(event->m_Type != EventType_UIFocusNext)
//		return vFalse;
//	focusEvent->currFocus = (myControl*)event->m_pUser;
//	return vTrue;
//}

TBool myCtrlMessage::translateUIFocusPrevMessage( Message* msg,UIFocus* focusEvent )
{
	focusEvent->currFocus = myControl::castFrom(msg->getMessage());
	return vTrue;
}

Sky::NType::TBool myCtrlMessage::translateUIFocusNextMessage( Message* msg,UIFocus* focusEvent )
{
	focusEvent->currFocus = myControl::castFrom(msg->getMessage());
	return vTrue;
}

Sky::NValue::MsgStatus myCtrlMessage::invokeHandler( myEventManager* manager,Handler* handler )
{
	xAssert(_event && handler);
	return handler->invokeHandler(manager,this);
}

}